package com.nec.recommend.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.nec.recommend.auth.AuthUser;
import com.nec.recommend.common.Result;
import com.nec.recommend.common.ResultCode;
import com.nec.recommend.consts.TokenConst;
import com.nec.recommend.utils.AuthUserUtils;
import com.nec.recommend.utils.RedisKeyUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletOutputStream;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

@Configuration
public class GlobalAuthInterceptor implements HandlerInterceptor {
    private final RedisTemplate<String, Object> redisTemplate;
    private final ObjectMapper objectMapper;

    public GlobalAuthInterceptor(RedisTemplate<String, Object> redisTemplate, ObjectMapper objectMapper) {
        this.redisTemplate = redisTemplate;
        this.objectMapper = objectMapper;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String client = request.getHeader("client");
        if (StringUtils.isBlank(client)) {
            client = TokenConst.WEAPP;
        }
        String token = request.getHeader(client + TokenConst.TOKEN_HEADER);
        if (Strings.isNotEmpty(token)) {
            Object o = redisTemplate.opsForValue().get(RedisKeyUtil.getAuthKey(client, token));
            if (Objects.nonNull(o)) {
                AuthUserUtils.setUser((AuthUser) o);
                return true;
            }
        }
        returnNoLogin(response);
        return false;
    }

    private void returnNoLogin(ServletResponse response) {
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        try (ServletOutputStream outputStream = httpServletResponse.getOutputStream()) {
            httpServletResponse.setStatus(ResultCode.SUCCESS.getCode());
            httpServletResponse.setContentType("Application/json;charset=utf-8");
            outputStream.write(objectMapper.writeValueAsString(Result.ofStatus(ResultCode.UN_AUTHENTICATION)).getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        //刷新用户会话时间
        AuthUserUtils.refreshSessionTime(request.getHeader("client"), redisTemplate);
        //释放空间
        AuthUserUtils.removeUser();
    }
}
